package cn.charlotte.pit.commands.player;


import cn.charlotte.pit.ThePit;
import cn.charlotte.pit.commands.PitCommands;
import cn.charlotte.pit.data.PlayerProfile;
import cn.charlotte.pit.data.sub.OfferData;
import cn.charlotte.pit.data.temp.TradeRequest;
import cn.charlotte.pit.events.EventFactory;
import cn.charlotte.pit.game.runnable.TradeMonitorRunnable;
import cn.charlotte.pit.menu.offer.OfferMenu;
import cn.charlotte.pit.menu.trade.TradeManager;
import cn.charlotte.pit.menu.trade.TradeMenu;
import cn.charlotte.pit.util.PlayerUtil;
import cn.charlotte.pit.util.chat.CC;
import cn.charlotte.pit.util.chat.ChatComponentBuilder;
import cn.charlotte.pit.util.inventory.InventoryUtil;
import cn.charlotte.pit.util.item.ItemUtil;
import cn.charlotte.pit.util.level.LevelUtil;
import cn.charlotte.pit.util.rank.RankUtil;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.*;
import co.aikar.commands.bukkit.contexts.OnlinePlayer;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import java.util.Calendar;

@CommandAlias("trade")
public class Trade extends BaseCommand {
    private final PitCommands pitCommands;

    public Trade(PitCommands pitCommands) {
        this.pitCommands = pitCommands;
    }


    @Subcommand("limit|limits")
    @CommandAlias("limit")
    public void sendTradeLimits(Player player) {
        PlayerProfile profile = PlayerProfile.getPlayerProfileByUuid(player.getUniqueId());
        long now = System.currentTimeMillis();
        long date = profile.getTradeLimit().getLastRefresh();
        //获取今天的日期
        String nowDay = this.pitCommands.dateFormat.format(now);
        //对比的时间
        String day = this.pitCommands.dateFormat.format(date);

        //daily reset
        if (!day.equals(nowDay) && Calendar.getInstance().get(Calendar.HOUR_OF_DAY) >= 4) {
            profile.getTradeLimit().setLastRefresh(now);
            profile.getTradeLimit().setAmount(0);
            profile.getTradeLimit().setTimes(0);
        }
        player.sendMessage(CC.translate("&6&l每日交易限制! &7(每日4:00 AM重置)"));
        player.sendMessage(CC.translate("&7每日硬币交易上限: " + (profile.getTradeLimit().getAmount() >= 50000 ? "&c" : "&a") + profile.getTradeLimit().getAmount() + "&7/&650000g"));
        player.sendMessage(CC.translate("&7每日交易次数上限: &e" + profile.getTradeLimit().getTimes() + "/25"));
    }

    @Subcommand("viewOffer|viewoffer")
    @CommandAlias("@players")
    public void viewOffer(Player player, OnlinePlayer target) {
        PlayerProfile profile = PlayerProfile.getPlayerProfileByUuid(player.getUniqueId());
        PlayerProfile targetProfile = PlayerProfile.getOrLoadPlayerProfileByUuid(target.player.getUniqueId());
        if (targetProfile.getOfferData().getBuyer() == null || !targetProfile.getOfferData().getBuyer().equals(player.getUniqueId())) {
            player.sendMessage(CC.translate("&c你没有来自此玩家的交易报价!"));
            return;
        }

        if (targetProfile.getOfferData().hasUnclaimedOffer()) {
            player.sendMessage(CC.translate("&c此交易报价已过期!"));
            return;
        }

        if (!profile.getCombatTimer().hasExpired()) {
            player.sendMessage(CC.translate("&c你无法在战斗中使用此功能!"));
            return;
        }

        if (profile.getTradeLimit().getTimes() >= 25) {
            player.sendMessage(CC.translate("&c你今天的交易次数已经达到上限!"));
            player.sendMessage(CC.translate("&c使用 &e/tradeLimits &c查看你的今日交易上限情况."));
            return;
        }

        if (profile.getTradeLimit().getAmount() + targetProfile.getOfferData().getPrice() >= 50000) {
            player.sendMessage(CC.translate("&c对方的开价加上今日已交易量已超过交易上限,因此你无法接受此交易报价."));
            player.sendMessage(CC.translate("&c使用 &e/tradeLimits &c查看你的今日交易上限情况."));
            return;
        }

        if (!player.getName().equalsIgnoreCase(player.getDisplayName())) {
            player.sendMessage(CC.translate("&c你无法在匿名模式下使用交易功能!"));
            return;
        }

        if (profile.getLevel() < 60) {
            player.sendMessage(CC.translate("&c&l等级不足! &7此指令在 " + LevelUtil.getLevelTag(profile.getPrestige(), 60) + " &7时解锁."));
            return;
        }

        new OfferMenu(target.player).openMenu(player);
    }

    @Subcommand("offer")
    @CommandCompletion("* [价格]|500|1000")
    public void offerItem(Player player, Player target, String price) {
        PlayerProfile profile = PlayerProfile.getPlayerProfileByUuid(player.getUniqueId());
        if (profile.getOfferData().hasActiveOffer()) {
            player.sendMessage(CC.translate("&c你当前有一个正在进行中的交易报价!"));
            return;
        } else if (profile.getOfferData().hasUnclaimedOffer()) {
            if (InventoryUtil.isInvFull(player)) {
                player.sendMessage(CC.translate("&c你有一个未结算的交易报价,请将背包腾出空间后重试!"));
            } else {
                InventoryUtil.addInvReverse(player.getInventory(), profile.getOfferData().getItemStack());
                profile.setOfferData(new OfferData());
                player.sendMessage(CC.translate("&c你有一个未结算的交易报价,相关物品已退还到你的背包.要发起一个新的交易报价,请再次输入此指令."));
            }
            return;
        }
//        if (targetPlayer.equals("#null") || price.equals("#null")) {
//            player.sendMessage(CC.translate("&c&l错误的使用方法! &7请手持要出售的物品,输入 &e/offer 玩家名 你的出价 &7来向此玩家发送一个报价请求,对方同意后将获得你提供的物品,你获得出价的硬币."));
//            return;
//        }
        try {
            if (Integer.parseInt(price) <= 0) {
                throw new Error("illegal price");
            }
        } catch (Exception e) {
            player.sendMessage(CC.translate("&c你输入的价格有误!"));
            return;
        }
        if (target == null || !target.isOnline() || PlayerUtil.isVanished(target)) {
            player.sendMessage(CC.translate("&c你选择的玩家不在线!"));
            return;
        }
        PlayerProfile targetProfile = PlayerProfile.getOrLoadPlayerProfileByUuid(target.getUniqueId());

        if (player.getUniqueId().equals(target.getUniqueId())) {
            player.sendMessage(CC.translate("&c你无法选择此玩家进行交易!"));
            return;
        }
        if (!profile.getCombatTimer().hasExpired()) {
            player.sendMessage(CC.translate("&c你无法在战斗中使用此功能!"));
            return;
        }

        // 当前时间
        long now = System.currentTimeMillis();
        long date = profile.getTradeLimit().getLastRefresh();
        //获取今天的日期
        String nowDay = this.pitCommands.dateFormat.format(now);
        //对比的时间
        String day = this.pitCommands.dateFormat.format(date);

        //daily reset
        if (!day.equals(nowDay) && Calendar.getInstance().get(Calendar.HOUR_OF_DAY) >= 4) {
            profile.getTradeLimit().setLastRefresh(now);
            profile.getTradeLimit().setAmount(0);
            profile.getTradeLimit().setTimes(0);
        }

        if (profile.getTradeLimit().getTimes() >= 25) {
            player.sendMessage(CC.translate("&c你今天的交易次数已经达到上限! (25/25)"));
            player.sendMessage(CC.translate("&c使用 &e/tradeLimits &c查看你的今日交易上限情况."));
            return;
        }

        if (profile.getTradeLimit().getAmount() + Integer.parseInt(price) >= 50000) {
            player.sendMessage(CC.translate("&c你的开价加上今日已交易量已超过交易上限,因此你无法发起此交易报价."));
            player.sendMessage(CC.translate("&c使用 &e/tradeLimits &c查看你的今日交易上限情况."));
            return;
        }

        if (!player.getName().equalsIgnoreCase(player.getDisplayName())) {
            player.sendMessage(CC.translate("&c你无法在匿名模式下使用交易功能!"));
            return;
        }

        if (profile.getLevel() < 60) {
            player.sendMessage(CC.translate("&c&l等级不足! &7此指令在 " + LevelUtil.getLevelTag(profile.getPrestige(), 60) + " &7时解锁."));
            return;
        }

        if (player.getItemInHand() == null || player.getItemInHand().getType() == Material.AIR) {
            player.sendMessage(CC.translate("&c请手持你要出售的物品再设置出售对象与价格!"));
            return;
        }

        if (!ItemUtil.canTrade(player.getItemInHand())) {
            player.sendMessage(CC.translate("&c此物品无法用于交易!"));
            return;
        }

        //todo: create offer
        profile.getOfferData().createOffer(target.getUniqueId(), player.getItemInHand(), Integer.parseInt(price));
        player.setItemInHand(new ItemStack(Material.AIR));
        if (!targetProfile.getPlayerOption().isTradeNotify() && !player.hasPermission(PlayerUtil.getStaffPermission())) {
            player.sendMessage(CC.translate("&c对方在游戏选项之后中设置了不接受交易请求,因此无法查看你的请求提示."));
            player.sendMessage(CC.translate("&c但对方仍可以通过使用 &e/viewOffer " + player.getName() + " &c以同意你的请求."));
        } else {
            player.sendMessage(CC.translate("&e&l交易报价发送! &7成功向 " + LevelUtil.getLevelTag(targetProfile.getPrestige(), targetProfile.getLevel()) + " " + RankUtil.getPlayerColoredName(target.getUniqueId()) + " &7发送了交易报价!"));
            target.sendMessage(
                    new ChatComponentBuilder(
                            CC.translate("&e&l交易报价! " + LevelUtil.getLevelTag(profile.getPrestige(), profile.getLevel()) + " " + RankUtil.getPlayerColoredName(player.getUniqueId()) + " &7向你发送了交易报价,请")
                    ).append(
                                    new ChatComponentBuilder(CC.translate(" &e点击这里"))
                                            .setCurrentHoverEvent(HoverEvent.showText(new ChatComponentBuilder(CC.translate("&6点击以接受")).build()))
                                            .setCurrentClickEvent(ClickEvent.runCommand("/trade viewoffer " + player.getName())).build())
                            .append(CC.translate(" &r&7以查看此交易报价."))
                            .build());
        }
    }

    @Subcommand("gui|AuctionGui|auction")
    public void openAuctionGui(Player player) {
        EventFactory eventFactory = ThePit.getInstance().getEventFactory();
        //check if event is available
        if (eventFactory.getActiveNormalEvent() == null || !"auction".equals(eventFactory.getActiveNormalEventName())) {
            player.sendMessage(CC.translate("&c此指令当前无法使用!"));
            return;
        }
        ThePit.getApi().openAuctionMenu(player);
    }


    @CatchUnknown
    @CommandCompletion("@players")
    public void onRequestTrade(Player player, OnlinePlayer target) {
        Player targetPlayer = target.player;
        if (player.getUniqueId().equals(targetPlayer.getUniqueId())) {
            player.sendMessage(CC.translate("&c你无法选择此玩家进行交易!"));
            return;
        }
        PlayerProfile profile = PlayerProfile.getPlayerProfileByUuid(player.getUniqueId());
        PlayerProfile targetProfile = PlayerProfile.getPlayerProfileByUuid(targetPlayer.getUniqueId());
        if (!profile.getCombatTimer().hasExpired()) {
            player.sendMessage(CC.translate("&c你无法在战斗中使用此功能!"));
            return;
        }

        // 当前时间
        long now = System.currentTimeMillis();
        long date = profile.getTradeLimit().getLastRefresh();
        //获取今天的日期
        String nowDay = pitCommands.dateFormat.format(now);
        //对比的时间
        String day = pitCommands.dateFormat.format(date);

        //daily reset
        if (!day.equals(nowDay) && Calendar.getInstance().get(Calendar.HOUR_OF_DAY) >= 4) {
            profile.getTradeLimit().setLastRefresh(now);
            profile.getTradeLimit().setAmount(0);
            profile.getTradeLimit().setTimes(0);
        }

        if (profile.getTradeLimit().getTimes() >= 25) {
            player.sendMessage(CC.translate("&c你今天的交易次数已经达到上限! (25/25)"));
            player.sendMessage(CC.translate("&c使用 &e/tradeLimits &c查看你的今日交易上限情况."));
            return;
        }

        if (!player.getName().equalsIgnoreCase(player.getDisplayName())) {
            player.sendMessage(CC.translate("&c你无法在匿名模式下使用交易功能!"));
            return;
        }

        if (profile.getLevel() < 60) {
            player.sendMessage(CC.translate("&c&l等级不足! &7此指令在 " + LevelUtil.getLevelTag(profile.getPrestige(), 60) + " &7时解锁."));
            return;
        }

        for (TradeRequest tradeRequest : TradeMonitorRunnable.getTradeRequests()) {
            if (tradeRequest.getTarget().equals(player.getUniqueId()) && tradeRequest.getPlayer().equals(target.getPlayer().getUniqueId())) {
                TradeManager tradeManager = new TradeManager(player, targetPlayer);
                new TradeMenu(tradeManager).openMenu(player);
                new TradeMenu(tradeManager).openMenu(targetPlayer);
                return;
            }
            if (tradeRequest.getTarget().equals(target.getPlayer().getUniqueId()) && tradeRequest.getPlayer().equals(player.getUniqueId())) {
                player.sendMessage(CC.translate("&c你已经发送过请求了,请等待对方接受!"));
                return;
            }
        }

        TradeMonitorRunnable.getTradeRequests().add(new TradeRequest(player.getUniqueId(), targetPlayer.getUniqueId()));
        if (!targetProfile.getPlayerOption().isTradeNotify() && !player.hasPermission(PlayerUtil.getStaffPermission())) {
            player.sendMessage(CC.translate("&c对方在游戏选项之后中设置了不接受交易请求,因此无法查看你的请求提示."));
            player.sendMessage(CC.translate("&c但对方仍可以通过使用 &e/trade " + player.getName() + " &c以同意你的请求."));
            return;
        } else {
            player.sendMessage(CC.translate("&a&l交易请求发送! &7成功向 " + LevelUtil.getLevelTag(targetProfile.getPrestige(), targetProfile.getLevel()) + " " + RankUtil.getPlayerColoredName(targetPlayer.getUniqueId()) + " &7发送了交易请求!"));
        }

        targetPlayer.sendMessage(
                Component.text(CC.translate(
                        "&6&l交易请求! "
                                + LevelUtil.getLevelTag(profile.getPrestige(), profile.getLevel())
                                + " " + RankUtil.getPlayerColoredName(player.getUniqueId())
                                + " &7向你发送了交易请求,请"
                )).append(Component.newline()).append(
                        Component.text(CC.translate(" &6&o点击这里"))
                                .hoverEvent(HoverEvent.showText(new ChatComponentBuilder(CC.translate("&6点击以接受")).build()))
                                .clickEvent(ClickEvent.runCommand("/trade " + player.getName()))
                ).append(Component.text(CC.translate(" &r&7以接受交易请求."))));
    }

}
